// use std::ptr::{NonNull, Unique};
use std::{
  cell::{Cell, RefCell},
  fmt::Debug,
  ops::Deref,
  rc::Rc,
  rc::Weak,
  slice::SliceIndex,
};
// use std::cell::Cell;

pub fn bczd_5() {
  test22();
}

fn test1() {
  let v = Box::<i32>::new(5);
  println!("{}", v);
  let u = v;
  // println!("{}", v);
}

fn test2() {
  let v = Box::new(5);
  println!(
    "v={:p}, &v={:p}, v.len={}",
    v,
    &v,
    std::mem::size_of::<Box<i32>>()
  );
  let u = v; // v把指向的堆内存对象所有权交给了u，v自己变成无指向或者错误指向的对象，如果使用这时候的v会编译错误提示已经移动所有权
  println!(
    "u={:p}, &u={:p}, u.len={}",
    u,
    &u,
    std::mem::size_of::<Box<i32>>()
  );
}

fn test3() {
  let v1 = 1;
  let v2 = "hello".to_string();
  {
    // v1;
    // v2;
  }
  println!("v1={}", v1);
  // println!("v2={}", v2);
}

fn test4() {
  let v2 = Option::Some("hello".to_string());
  if let Some(ref v) = v2 {
    println!("v={}", v);
  }
  println!("v2={:?}", v2);
  println!("v2={:?}", v2);
}

fn test5() {
  let v2 = Option::Some("hello".to_string());
  let ref vv2 = v2;
  let ref vv3 = v2;
  // let ref mut vv4 = v2;
  println!("v2={:?}", v2);
  println!("v2={:?}", v2);
}

fn test6() {
  let ref v2 = Option::Some("hello".to_string());
  let vv2 = v2;
  let ref vv3 = v2;
  println!("v2={:p}, &v2={:p}", v2, &v2);
  println!("vv2={:p}, &vv2={:p}", vv2, &vv2);
  println!(
    "*vv3={:p}, vv3={:p}, &vv3={:p}, &&vv3={:p}",
    *vv3, vv3, &vv3, &&vv3
  );
}

fn test7() {
  fn borrowed(value: &String) {
    println!("value={:?}", value);
  }
  let v2 = "hello".to_string();
  let vv2 = v2;
  // println!("v2={:?}, v2={:p}", v2, &v2); // 等价1
  // borrowed(&v2);// 等价2
}

fn test8() {
  let not_copy_value = "hello".to_string(); // 不可复制，只能移动
  let mut mut_ref = 3i32; // 可以复制，可以改变
  let const_ref = 4i32; // 可以复制，不可改变
  let mut f = || {
    fn mut_println(data: &mut i32) {
      println!("{:?}", data);
    }
    fn const_println(data: &i32) {
      println!("{:?}", data);
    }
    fn copy_println(data: &String) {
      println!("{:?}", data);
    }
    // let local_not_copy_value = not_copy_value;
    // let local_mut_ref = &mut mut_ref;
    // let local_const_ref = &const_ref;
    // println!("local_not_copy_value={}", local_not_copy_value);
    // println!("local_mut_ref={}", local_mut_ref);
    // println!("mut_ref={}", &mut mut_ref);
    mut_println(&mut mut_ref);
    const_println(&const_ref);
    copy_println(&not_copy_value);
    // println!("local_const_ref={}", local_const_ref);
  };
  f();
  println!("not_copy_value={}", not_copy_value);
  println!("mut_ref={}", mut_ref);
  println!("const_ref={}", const_ref);
}
fn test9() {
  let not_copy_value = "hello".to_string(); // 不可复制，只能移动
  let mut mut_ref = 3i32; // 可以复制，可以改变
  let const_ref = 4i32; // 可以复制，不可改变
  let mut f = || {
    println!("not_copy_value={}", not_copy_value);
    println!("mut_ref={}", &mut mut_ref);
    println!("const_ref={}", const_ref);
  };
  f();
  println!("not_copy_value={}", not_copy_value);
  println!("mut_ref={}", mut_ref);
  println!("const_ref={}", const_ref);
}
fn test10() {
  let not_copy_value = "hello".to_string(); // 不可复制，只能移动
  let mut_ref = 3i32; // 可以复制，可以改变
  let const_ref = 4i32; // 可以复制，不可改变
  let f = || {
    fn mut_println(data: i32) {
      println!("{:?}", data);
    }
    fn const_println(data: i32) {
      println!("{:?}", data);
    }
    fn copy_println(data: String) {
      println!("{:?}", data);
    }
    mut_println(mut_ref);
    const_println(const_ref);
    copy_println(not_copy_value);
  };
  f();
  // println!("not_copy_value={}", not_copy_value);
  println!("mut_ref={}", mut_ref);
  println!("const_ref={}", const_ref);
}
fn test11() {
  let v1 = 1i32;
  let ref vv1 = v1;
  let v2 = v1;
  let vv2 = &v2;
  println!(
    "vv1_*={}, vv1_v={}, vv1={:p}, &vv1={:p}",
    *vv1, vv1, vv1, &vv1
  );
  println!(
    "vv2_*={}, vv2_v={}, vv2={:p}, &vv2={:p}",
    *vv2, vv2, vv2, &vv2
  );
}
fn test12() {
  let mut v1 = 1i32;
  let ref mut vv1 = v1;
  *vv1 = 2;
  let mut v2 = 1i32;
  let vv2 = &mut v2;
  *vv2 = 2;
}

fn test13() {
  fn test<'a, 'b: 'a>(v1: &'a str, v2: &'b str) -> &'a str {
    if v1.len() > v2.len() {
      return v1;
    }
    return v2;
  }
  let v1 = "123";
  let ret;
  {
    let v2 = "1234";
    ret = test(v1, v2);
  }
  // let v2 = "1234";
  // let ret = test(v1, v2);
  println!("{}", ret);
}

fn test14() {
  struct Test<'a> {
    v1: i32,
    v2: &'a str,
  }
}

fn test15() {
  trait Foo {}
  struct Bar<'a> {
    x: &'a i32,
  }
  impl<'a> Foo for Bar<'a> {}
  let num = 5;
  let box_num = Box::new(Bar { x: &num });
  let box_num_cvt = box_num as Box<dyn Foo>;
  let foo_num: Box<dyn Foo> = Box::new(Bar { x: &num });
}

fn test16() {
  trait Foo<'a> {}
  struct FooImpl<'a> {
    s: &'a [u32],
  }
  impl<'a> Foo<'a> for FooImpl<'a> {}
  fn foo<'a>(s: &'a [u32]) -> Box<dyn Foo<'a> + 'a> {
    Box::new(FooImpl { s: s })
  }
}

fn test17() {
  // pub struct MyBox<T: ?Sized>(Unique<T>);
  // impl<T: Clone> Clone for MyBox<T> {
  //   fn clone(&self) -> Self {
  //       Self(self.0.clone())
  //   }
  //   // #[inline]
  //   // fn clone(&self) -> Self {
  //   //     // Pre-allocate memory to allow writing the cloned value directly.
  //   //     // let mut boxed = Self::new_uninit_in(self.1.clone());
  //   //     unsafe {
  //   //         (**self).write_clone_into_raw(boxed.as_mut_ptr());
  //   //         // boxed.assume_init()
  //   //     }
  //   // }
  //   // fn get(&self)->&T {
  //   //   &**self
  //   // }
  // }
  // #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
  // impl<T: ?Sized> AsRef<T> for MyBox<T> {
  //   fn as_ref(&self) -> &T {
  //     // &(*self.0)
  //     &**self
  //   }
  // }
}

fn test18() {
  #[derive(Debug)]
  struct TestDrop<T>
  where
    T: Sized + Debug,
  {
    value: T,
  }
  impl<T> Drop for TestDrop<T>
  where
    T: Sized + Debug,
  {
    fn drop(&mut self) {
      println!("{:?}", self);
    }
  }
  let v1 = Rc::new(TestDrop { value: 1 });
  let v2 = v1.clone();
  println!("{:?}", v2.clone());
}

fn test19() {
  #[derive(Debug)]
  struct Node<T>
  where
    T: Sized + Debug,
  {
    value: T,
    next: Option<Rc<RefCell<Node<T>>>>,
    head: Option<Weak<RefCell<Node<T>>>>,
  }
  impl<T> Drop for Node<T>
  where
    T: Sized + Debug,
  {
    fn drop(&mut self) {
      println!("{:?}", self);
    }
  }
  let first = Rc::new(RefCell::new(Node {
    value: 1,
    next: None,
    head: None,
  }));
  let second = Rc::new(RefCell::new(Node {
    value: 1,
    next: None,
    head: None,
  }));
  let third = Rc::new(RefCell::new(Node {
    value: 1,
    next: None,
    head: None,
  }));
  // third.borrow_mut().head = Some(Rc::downgrade(&first));
  // second.borrow_mut().next = Some(third);
  // first.deref().borrow_mut().next = Some(second);

  first.deref().borrow_mut().next = Some(second.clone());
  second.borrow_mut().next = Some(third.clone());
  third.borrow_mut().head = Some(Rc::downgrade(&first));
}

fn test20() {
  struct TestObject {
    v1: i32,
    v2: Cell<i32>,
  }
  let v1 = TestObject {
    v1: 1,
    v2: Cell::new(1),
  };
  println!("{:?}", v1.v1);
  println!("{:?}", v1.v2.get());
  v1.v2.set(2);
  println!("{:?}", v1.v2.get());
}

fn test21() {
  pub struct MyUnsafeCell<T: ?Sized> {
    value: T,
  }

  impl<T> MyUnsafeCell<T> {
    pub const fn new(value: T) -> MyUnsafeCell<T> {
      MyUnsafeCell { value }
    }
    fn get(&self) -> *mut T {
      self as *const MyUnsafeCell<T> as *const T as *mut T
    }
  }

  // impl<T: ?Sized> Deref for MyUnsafeCell<T> {
  //   type Target = T;

  //   fn deref(&self) -> &Self::Target {
  //     &self.value
  //   }
  // }

  impl<T> From<T> for MyUnsafeCell<T> {
    fn from(t: T) -> MyUnsafeCell<T> {
      MyUnsafeCell::new(t)
    }
  }

  pub struct MyCell<T: ?Sized> {
    value: MyUnsafeCell<T>,
  }

  impl<T> MyCell<T> {
    pub const fn new(value: T) -> MyCell<T> {
      MyCell {
        value: MyUnsafeCell::new(value),
      }
    }
  }

  impl<T: Copy> MyCell<T> {
    pub fn get(&self) -> T {
      // SAFETY: This can cause data races if called from a separate thread,
      // but `Cell` is `!Sync` so this won't happen.
      unsafe {
        // *self.value.get() // 1
        let ret1: *mut T = (*self).value.get(); // 2
        let ret2 = *(self.value.get()); // 3
                                        // *ret1
        ret2
      }
    }
  }

  let v1: MyCell<i32> = MyCell::new(1);
  let v2 = v1.get();
  println!("调试std源码:{:?}", v2);
}

fn test22() {
  fn f1(data: &mut [char]) {}
  let mut data = vec!['a', 'b', 'c'];
  let slice = &mut data[..];
  f1(slice);
  data.push('d');
}
